/*
 * Copyright (C) 2020, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * Authors: zhangpengfei <zhangpengfei@kylinos.cn>
 *
 */
#include "construct-document.h"
#include "file-utils.h"
#include "chinese-segmentation.h"
#include <QDebug>
#include <QThread>
#include <QUrl>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

//extern QList<Document> *_doc_list_path;
//extern QMutex  _mutex_doc_list_path;
using namespace Zeeker;
ConstructDocumentForPath::ConstructDocumentForPath(QVector<QString> list) {
    this->setAutoDelete(true);
    m_list = std::move(list);
}

void ConstructDocumentForPath::run() {
//    qDebug()<<"ConstructDocumentForPath";
//    if(!Zeeker::_doc_list_path)
//        Zeeker::_doc_list_path = new QVector<Document>;
//    qDebug()<<_doc_list_path->size();
//    qWarning()<<"ConstructDocumentForPath";

    QString index_text = m_list.at(0).toLower();
    QString sourcePath = m_list.at(1);
    Document doc;
    QMimeType type = FileUtils::getMimetype(sourcePath);
    QString name = type.name();
    QStringList list = sourcePath.split("/");
    qWarning("sourcePath: %s\n", sourcePath.toLatin1().data());
    bool istmp=sourcePath.contains("UltraSearch/im2txt/tmp",Qt::CaseInsensitive);
    qWarning("istmp: %d\n", istmp);  
    bool ispng=list.last().contains(".png",Qt::CaseInsensitive);
    bool isdoc=list.last().contains(".doc",Qt::CaseInsensitive);
    bool isjpg=list.last().contains(".jpg",Qt::CaseInsensitive);
    bool isjpeg=list.last().contains(".jpeg",Qt::CaseInsensitive);
    bool ispdf=list.last().contains(".pdf",Qt::CaseInsensitive);
    bool isdocx=list.last().contains(".docx",Qt::CaseInsensitive);
    bool istxt=list.last().contains(".txt",Qt::CaseInsensitive);
    bool iserrortxt=false;
    if(list.last()=="pinyinWithoutTone.txt"||list.last()=="pinyinWithTone.txt")
    iserrortxt = true;
    bool isCorrectTextMimeType=false;
    if (name == "application/zip"||name == "text/plain"||
    type.inherits("application/msword") || type.name() == "application/x-ole-storage"||name == "application/pdf")
    isCorrectTextMimeType=true;

    if((!istmp)&&((!iserrortxt)&&(isCorrectTextMimeType&&(isdoc||ispdf||istxt||isdocx))||(ispng||isjpg||isjpeg)))
    {
        qWarning("sourcePath: %s\n", list.last().toLatin1().data());
        char* socketenv = getenv("SEARCHSOCKET");
        // printf("%s",socketenv);
        int sockfd = atoi(socketenv);

        QByteArray ba = sourcePath.toLocal8Bit(); 
        write(sockfd, ba.data(), ba.size());
        ba.resize(1024);
        memset(ba.data(),0,ba.size());
        read(sockfd, ba.data(), ba.size());
        printf("get char from server: %s\n", ba.data());
        /* close the socket */
        // close(sockfd);
        // char* key="happy";
        // QString keyword(key);

        QString info=QString::fromLocal8Bit(ba.data());
        QStringList infolist=info.split("$$$");
        QString keyword=infolist.at(0);
        QString abstract=infolist.at(1);
        // printf("All keywords:%s\nAbstract:%s\n",keyword.toStdString().data(),abstract.toStdString().data());
        QStringList keywordList=keyword.split("##");
        QString filetype = keywordList.at(0);
        printf("filetype: %s\n", filetype.toStdString().data());
        QString txt = "T";
        QString pic = "P";
        QString tag;
        if(filetype==pic)
        {
        tag=keywordList.at(0)+"-"+keywordList.at(1)+"-"+keywordList.at(2)+"-"+keywordList.at(3);
        }else{ 
        tag =keywordList.at(0)+"-";}

        for (int i=1;i<keywordList.count();i++)
        {
            QString a = keywordList.at(i);
            // printf("keyword%d:%s\n",i+1,a.toStdString().data());
            doc.addTerm(QUrl::toPercentEncoding(a).toStdString());
        }
        // printf("%s\n",keyword.toStdString().data());

        doc.addValue(abstract,2);
        doc.addValue(tag,3);

    }
        Xapian::Document testdoc=doc.getXapianDocument();

        Xapian::TermIterator iterm = testdoc.termlist_begin();
        for (; iterm != testdoc.termlist_end(); ++iterm) {
        // std::cout << "Term:"<<*iterm << std::endl;
        }

    //多音字版
    //现加入首字母
    QStringList pinyin_text_list = FileUtils::findMultiToneWords(QString(m_list.at(0)).replace(".", ""));
//    if(!pinyin_text_list.isEmpty())
//    {
//        for (QString& i : pinyin_text_list){
//            i.replace("", " ");
//            i = i.simplified();
//        }
//        doc.setIndexText(pinyin_text_list);
//    }

    QString uniqueterm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath));
    QString upTerm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath.section("/", 0, -2, QString::SectionIncludeLeadingSep)));
//    qDebug()<<"sourcePath"<<sourcePath.section("/",0,-2,QString::SectionIncludeLeadingSep);
//    qDebug() << "sourcePath ---------------------------: " << sourcePath;
//    qDebug() << "sourcePath.section -------------------: " << sourcePath.section("/",0,-2,QString::SectionIncludeLeadingSep);
//    qDebug() << "ConstructDocumentForPath -- uniqueterm: " << uniqueterm;
//    qDebug() << "ConstructDocumentForPath -- upTerm:     " << upTerm;


    doc.setData(sourcePath);
    doc.setUniqueTerm(uniqueterm);
    doc.addTerm(upTerm);
    doc.addValue(m_list.at(2));
    /*    QStringList temp;
    //    temp.append(index_text);
        temp.append(pinyin_text_list)*/;
    int postingCount = 0;
    while(postingCount < index_text.size()) {
//        QVector<size_t> p;
//        p.append(postingCount);
        doc.addPosting(QUrl::toPercentEncoding(index_text.at(postingCount)).toStdString(), postingCount);
        ++postingCount;
    }
    int i = 0;
    for(QString& s : pinyin_text_list) {
        i = 0;
        while(i < s.size()) {
            doc.addPosting(QUrl::toPercentEncoding(s.at(i)).toStdString(), postingCount);
            ++postingCount;
            ++i;
        }
    }

//    QMetaObject::invokeMethod(m_indexGenerator,"appendDocListPath",Q_ARG(Document,doc));
    IndexGenerator::_mutex_doc_list_path.lock();
    IndexGenerator::_doc_list_path.append(doc);
    IndexGenerator::_mutex_doc_list_path.unlock();
//    qDebug()<<"ConstructDocumentForPath finish";
    return;
}

ConstructDocumentForContent::ConstructDocumentForContent(QString path) {
    this->setAutoDelete(true);
    m_path = std::move(path);
}

void ConstructDocumentForContent::run() {
//    qDebug() << "ConstructDocumentForContent  currentThreadId()" << QThread::currentThreadId();
    //      构造文本索引的document
//    if(!Zeeker::_doc_list_content)
//        Zeeker::_doc_list_content = new QVector<Document>;
    QString content;
    FileReader::getTextContent(m_path, content);
    if(content.isEmpty())
        return;
    //QString uniqueterm = QString::fromStdString(FileUtils::makeDocUterm(m_path));
    //QString upTerm = QString::fromStdString(FileUtils::makeDocUterm(m_path.section("/", 0, -2, QString::SectionIncludeLeadingSep)));
    Document doc;
    doc.setData(content);
    //doc.setUniqueTerm(uniqueterm);
    doc.setUniqueTerm(FileUtils::makeDocUterm(m_path));
    //doc.addTerm(upTerm);
    doc.addTerm(FileUtils::makeDocUterm(m_path.section("/", 0, -2, QString::SectionIncludeLeadingSep)));
    doc.addValue(m_path);

    //'\xEF\xBC\x8C' is "，" "\xE3\x80\x82" is "。"  use three " " to replace ,to ensure the offset info.
    content = content.replace("\t", " ").replace("\xEF\xBC\x8C", "   ").replace("\xE3\x80\x82", "   ");

//    QVector<SKeyWord> term = ChineseSegmentation::getInstance()->callSegement(content.left(20480000));
    std::vector<cppjieba::KeyWord> term = ChineseSegmentation::getInstance()->callSegementStd(content.left(20480000).toStdString());

    for(size_t i = 0; i < term.size(); ++i) {
        doc.addPosting(term.at(i).word, term.at(i).offsets, static_cast<int>(term.at(i).weight));
    }

    IndexGenerator::_mutex_doc_list_content.lock();
    IndexGenerator::_doc_list_content.append(doc);
    IndexGenerator::_mutex_doc_list_content.unlock();
    content.clear();
    content.squeeze();

    term.clear();
    term.shrink_to_fit();
    return;
}
